package edu.hawaii.myisern.action;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import edu.hawaii.myisern.model.MyIsernModel;
import edu.hawaii.myisern.researchers.jaxb.Researcher;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;


/**
 * Allows for a researcher to be added or edited. 
 * 
 * @author Jon Lao
 * @author Jared Sunouchi
 * @author Chiao-Fen Zielinski-Liu
 */
public class ResearcherActionBean implements ActionBean {
  /** Required by the ActionBean interface. */
  private ActionBeanContext context;
  /** An error string, always displayed, but invisible if empty. */
  private String errorMessage = "";
  /** Add label and type. */
  private String addType;
  /** Edit label and type. */
  private String editType;
  /** Added? */
  private boolean added;
  /** Editing? */
  private boolean editing;
  /** Edited? */
  private boolean edited;
  /** The single MyIsern instance manipulated by all webapp users. */
  private MyIsernModel myIsern = MyIsernModel.getInstance();
  /** Researcher attributes */
  private String name;
  private String organization;
  private String email;
  private String pictureLink;
  private String bioStatement;
  
  private String researcher = "Researcher";
  private List<String> researcherNames;
  
  /**
   * Returns the context. Required by the interface. 
   * 
   * @return the ActionBeanContext.
   */
  public ActionBeanContext getContext() {
    return context;
  }
  
  /**
   * Sets the context. Required by the interface. 
   * 
   * @param context The ActionBeanContext to set. 
   */
  public void setContext(ActionBeanContext context) {
    this.context = context;
  }
  
  /**
   * Returns the error message, which may be empty.
   * Indicates if an error was made adding or editing the researcher. 
   * 
   * @return The error message. 
   */
  public String getErrorMessage() {
    return this.errorMessage;
  }
  
  /**
   * Returns the appropriate add label.
   * 
   * @return The add label. 
   */
  public String getAddType() {
    return this.addType;
  }
  
  /**
   * Returns the appropriate edit label.
   * 
   * @return The edit label. 
   */
  public String getEditType() {
    return this.editType;
  }
  
  /**
   * Returns the whether the researcher has been added or not.
   * 
   * @return Whether the researcher has been added or not. 
   */
  public boolean getAdded() {
    return this.added;
  }
  
  /**
   * Returns the whether the researcher has been edited or not.
   * 
   * @return Whether the researcher has been edited or not. 
   */
  public boolean getEdited() {
    return this.edited;
  }
  
  /**
   * Returns the whether the researcher is being edited or not.
   * 
   * @return Whether the researcher is being edited or not. 
   */
  public boolean getEditing() {
    return this.editing;
  }
  
  /**
   * Creates and returns the list of researcher names.
   * 
   * @return The list of researcher names.
   */
  public List<String> getResearcherNames() {
    List<Researcher> researcherList = myIsern.getResearchers();
    List<String> researcherNamesList = new ArrayList<String>();
    for (Researcher res : researcherList) {
      researcherNamesList.add(res.getName());
    }
    Collections.sort(researcherNamesList);
    this.researcherNames = researcherNamesList;
    
    return this.researcherNames;
  }
  
  /**
   * Displays the form to add a researcher.
   * 
   * @return A Resolution indicating to redisplay the add.jsp page.
   */
  public Resolution researcherForm() {
    this.addType = researcher;
    return new ForwardResolution("/add.jsp");
  }
  
  /**
   * Displays the form to edit a researcher.
   * 
   * @return A Resolution indicating to redisplay the edit.jsp page.
   */
  public Resolution editResearcherForm() {
    this.editType = researcher;
    return new ForwardResolution("/edit.jsp");
  }
  
  /**
   * Sets the name of the researcher.
   * 
   * @param name The name to set.
   */
  public void setName(String name) {
    this.name = name.trim();
  }
  
  /**
   * Returns the name of the researcher.
   * 
   * @return The name of the researcher.
   */
  public String getName() {
    return this.name;
  }
  
  /**
   * Sets the organization of the researcher.
   * 
   * @param organization The organization to set.
   */
  public void setOrganization(String organization) {
    this.organization = organization.trim();
  }
  
  /**
   * Returns the organization of the researcher.
   * 
   * @return The organization of the researcher.
   */
  public String getOrganization() {
    return this.organization;
  }
  
  /**
   * Sets the email of the researcher.
   * 
   * @param email The email to set.
   */
  public void setEmail(String email) {
    this.email = email.trim();
  }
  
  /**
   * Returns the email of the researcher.
   * 
   * @return The email of the researcher.
   */
  public String getEmail() {
    return this.email;
  }
  
  /**
   * Sets the picture-link of the researcher.
   * 
   * @param pictureLink The picture-link to set.
   */
  public void setPictureLink(String pictureLink) {
    this.pictureLink = pictureLink.trim();
  }
  
  /**
   * Returns the picture-link of the researcher.
   * 
   * @return The picture-link of the researcher.
   */
  public String getPictureLink() {
    return this.pictureLink;
  }
  
  /**
   * Sets the bio-statement of the researcher.
   * 
   * @param bioStatement The bio-statement to set.
   */
  public void setBioStatement(String bioStatement) {
    this.bioStatement = bioStatement.trim();
  }
  
  /**
   * Returns the bio-statement of the researcher.
   * 
   * @return The bio-statement of the researcher.
   */
  public String getBioStatement() {
    return this.bioStatement;
  }
  
  /**
   * Adds a researcher.
   * 
   * @return A Resolution indicating to redisplay the add.jsp page.
   * @throws Exception If problems occur.
   */
  public Resolution add() throws Exception {
    if (this.name == null) {
      this.errorMessage = "Please enter a name.";
    }
    else {
      List<Researcher> list = myIsern.getResearchers();
      boolean found = false;
      for (Researcher researcher : list) {
        if (researcher.getName().equals(this.name.replace('_', ' '))) {
          found = true;
        }
      }

      if (found) {
        this.errorMessage = "Researcher already exists. Please go to the edit page.";
      }
      else {
        Researcher newResearcher = new Researcher();
        newResearcher.setName(this.name);
        newResearcher.setOrganization(this.organization);
        newResearcher.setEmail(this.email);
        newResearcher.setPictureLink(this.pictureLink);
        newResearcher.setBioStatement(this.bioStatement);
        myIsern.addResearcher(newResearcher);
        this.added = true;
      }
    }
    this.addType = researcher;
    return new ForwardResolution("/add.jsp");
  }
  
  /**
   * Displays the information to edit.
   * 
   * @return A resolution indicating to redisplay the edit.jsp page.
   * @throws Exception If problems occur.
   */
  public Resolution displayEdit() throws Exception {
    if (this.name == null) {
      this.errorMessage = "Please enter a name.";
    }
    else {
      List<Researcher> list = myIsern.getResearchers();
      Researcher editResearcher = new Researcher();
      boolean found = false;
      for (Researcher researcher : list) {
        if (researcher.getName().equals(this.name.replace('_', ' '))) {
          editResearcher = researcher;
          found = true;
        }
      }

      if (found) {
        this.organization = editResearcher.getOrganization();
        this.email = editResearcher.getEmail();
        this.pictureLink = editResearcher.getPictureLink();
        this.bioStatement = editResearcher.getBioStatement();

        this.editing = true;
      }
      else {
        this.errorMessage = "Name was not found.";
      }
    }

    this.editType = researcher;
    return new ForwardResolution("/edit.jsp");
  }
  
  /**
   * Edits a researcher.
   * 
   * @return A resolution indicating to redisplay the edit.jsp page.
   * @throws Exception If problems occur.
   */
  public Resolution edit() throws Exception {
    List<Researcher> list = myIsern.getResearchers();
    int count = 0;
    Researcher editResearcher = new Researcher();
    for (Researcher researcher : list) {
      if (researcher.getName().equals(this.name.replace('_', ' '))) {
        editResearcher = researcher;
        count = list.indexOf(researcher);
      }
    }
    
    editResearcher.setOrganization(this.organization);
    editResearcher.setEmail(this.email);
    editResearcher.setPictureLink(this.pictureLink);
    editResearcher.setBioStatement(this.bioStatement);
    
    myIsern.editResearcher(count, editResearcher);
    
    this.edited = true;
    this.editing = true;
    this.editType = researcher;    
    return new ForwardResolution("/edit.jsp");
  }
  
  /**
   * Removes the researcher.
   * 
   * @return A resolution indicating to redisplay the add.jsp or edit.jsp page.
   * @throws Exception If problems occur.
   */
  public Resolution remove() throws Exception {    
    myIsern.removeResearcher(this.name);
    
    this.errorMessage = this.name + " has been removed.";
    return new ForwardResolution("/add.jsp");
  }
}
